package com.hello.sandbox.fake.service;

import android.content.pm.PackageManager;
import black.android.app.BRActivityThread;
import black.android.app.BRContextImpl;
import black.android.os.BRServiceManager;
import black.android.permission.BRIPermissionManagerStub;
import com.hello.sandbox.SandBoxCore;
import com.hello.sandbox.fake.hook.BinderInvocationStub;
import com.hello.sandbox.fake.service.base.PkgMethodProxy;
import com.hello.sandbox.fake.service.base.ValueMethodProxy;
import com.hello.sandbox.utils.Reflector;
import com.hello.sandbox.utils.compat.BuildCompat;

/** Created by BlackBox on 2022/3/2. */
public class IPermissionManagerProxy extends BinderInvocationStub {
  public static final String TAG = "IPermissionManagerProxy";

  private static final String P = "permissionmgr";

  public IPermissionManagerProxy() {
    super(BRServiceManager.get().getService(P));
  }

  @Override
  protected Object getWho() {
    return BRIPermissionManagerStub.get().asInterface(BRServiceManager.get().getService(P));
  }

  @Override
  protected void inject(Object baseInvocation, Object proxyInvocation) {
    replaceSystemService("permissionmgr");
    BRActivityThread.getWithException()._set_sPermissionManager(proxyInvocation);
    Object systemContext = BRActivityThread.get(SandBoxCore.mainThread()).getSystemContext();
    PackageManager packageManager = BRContextImpl.get(systemContext).mPackageManager();
    if (packageManager != null) {
      try {
        Reflector.on("android.app.ApplicationPackageManager")
            .field("mPermissionManager")
            .set(packageManager, proxyInvocation);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  protected void onBindMethod() {
    super.onBindMethod();
    addMethodHook(new ValueMethodProxy("addPermissionAsync", true));
    addMethodHook(new ValueMethodProxy("addPermission", true));
    addMethodHook(new ValueMethodProxy("performDexOpt", true));
    addMethodHook(new ValueMethodProxy("performDexOptIfNeeded", false));
    addMethodHook(new ValueMethodProxy("performDexOptSecondary", true));
    addMethodHook(new ValueMethodProxy("addOnPermissionsChangeListener", 0));
    addMethodHook(new ValueMethodProxy("removeOnPermissionsChangeListener", 0));
    addMethodHook(new ValueMethodProxy("checkDeviceIdentifierAccess", false));
    addMethodHook(new PkgMethodProxy("shouldShowRequestPermissionRationale"));
    if (BuildCompat.isOreo()) {
      addMethodHook(new ValueMethodProxy("notifyDexLoad", 0));
      addMethodHook(new ValueMethodProxy("notifyPackageUse", 0));
      addMethodHook(new ValueMethodProxy("setInstantAppCookie", false));
      addMethodHook(new ValueMethodProxy("isInstantApp", false));
    }
  }

  @Override
  public boolean isBadEnv() {
    return false;
  }
}
